fix/remove-custom-progressbar#1178
Conversation
cee4514 to
dd7e029
Compare
Benchmark comparisonThreshold: 20% (lower is better). No benchmark regression exceeded the configured threshold. No benchmark improvement exceeded the configured threshold. All benchmark results
|
980e0dc to
3b4ec66
Compare
…h native QProgressBar
b0faeb5 to
b6b768e
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
cea2f10 to
35ce5a4
Compare
There was a problem hiding this comment.
Pull request overview
Refactors the scan/device progress UI to remove custom-painted progress rendering and centralize progress-message tracking in a shared backend, improving robustness for widgets embedded in the BECMainWindow.
Changes:
- Replaces the custom-painted
BECProgressBarimplementation with a nativeQProgressBar-backed widget, while preserving state coloring and label formatting. - Introduces
BECProgressTracker(progress_backend.py) to unify scan/device progress subscription, task lifecycle, and snapshot emission across widgets. - Updates ScanProgressBar, Ring progress bar, and related unit tests to use the new tracker and the native progress bar behavior.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
bec_widgets/widgets/progress/progress_backend.py |
New shared progress tracking backend (source selection, task timing, snapshots, subscriptions). |
bec_widgets/widgets/progress/scan_progressbar/scan_progressbar.py |
Migrates ScanProgressBar to use BECProgressTracker and forwards UI updates from snapshots. |
bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py |
Replaces custom painting/animation with a native QProgressBar implementation + dynamic stylesheet handling. |
bec_widgets/widgets/progress/ring_progress_bar/ring.py |
Switches scan/device progress wiring to BECProgressTracker and updates cleanup/disconnect behavior. |
bec_widgets/widgets/containers/main_window/main_window.py |
Adjusts status-bar scan progress sizing and configures dynamic stylesheet behavior for compact/full variants. |
tests/unit_tests/test_bec_progressbar.py |
Updates tests to assert native QProgressBar behavior, formatting, and dynamic stylesheet logic. |
tests/unit_tests/test_scan_progress_bar.py |
Updates ScanProgressBar tests to reflect tracker-based lifecycle and new status mappings. |
tests/unit_tests/test_ring_progress_bar_ring.py |
Updates ring progress tests to expect tracker-based dispatcher connections and cleanup behavior. |
tests/unit_tests/test_device_initialization_progress_bar.py |
Adjusts assertions to read native QProgressBar text formatting. |
tests/unit_tests/test_main_widnow.py |
Adds coverage for compact scan progress sizing in the main window status bar. |
bec_widgets/cli/client.py |
Updates CLI proxy docstring to match the new native progress bar implementation. |
Comments suppressed due to low confidence (1)
bec_widgets/widgets/progress/scan_progressbar/scan_progressbar.py:27
- Docstring uses inconsistent capitalization for widget names. Use the actual class names/casing (BECProgressBar, QProgressBar) to avoid confusion and make it searchable.
"""
Widget to display a progress bar that is hooked up to the scan progress of a scan.
If you want to manually set the progress, it is recommended to use the BECProgressbar or QProgressbar directly.
"""
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
35ce5a4 to
181f530
Compare
b91c676 to
439da68
Compare
…empting to add QLayout "" to ScanGroupBox "", which already has a layout`
439da68 to
53cf334
Compare
45cb5f1 to
e049d04
Compare
e049d04 to
30b184c
Compare
| "open": cls.NORMAL, | ||
| "paused": cls.PAUSED, | ||
| "aborted": cls.INTERRUPTED, | ||
| "halt": cls.PAUSED, |
There was a problem hiding this comment.
I don't think there is a "halt" state, only "halted". Where did you get that from?
| "halt": cls.PAUSED, | ||
| "halted": cls.PAUSED, | ||
| "closed": cls.COMPLETED, | ||
| "user_completed": cls.PAUSED, |
There was a problem hiding this comment.
Now that the mapping doesn't contain the color anymore, do we really need it? It just maps an enum to a string. Why not just use the enum?
| config=None, | ||
| gui_id=None, | ||
| enable_dynamic_stylesheet: bool = True, | ||
| **kwargs, |
There was a problem hiding this comment.
I suggest to add a doc string, especially for the arguments that are not commonly used in BW like enable_dynamic_stylesheet
| elif "device_progress" in instruction: | ||
| device = instruction["device_progress"][0] | ||
| self.set_progress_source(ProgressSource.DEVICE_PROGRESS, device=device) | ||
| self.ui.elapsed_time_label.setText(task.time_elapsed) |
There was a problem hiding this comment.
when I run it in designer, I get:
in update_labels
self.ui.elapsed_time_label.setText(task.time_elapsed)
RuntimeError: Internal C++ object (PySide6.QtWidgets.QLabel) already deleted.
There was a problem hiding this comment.
All widgets which use ui files are having this error. It is a problem with ui loader. We have this bug for long time.
| Returns: | ||
| dict[str, list[str]]: Dictionary with the signals for the device | ||
| Ring device mode follows the previous progress-widget selection order: | ||
| progress signals first, then hinted readback signals, then normal readback signals. |
There was a problem hiding this comment.
probably leftover from a codex rewrite... I don't think we should have doc string references to code that we don't have anymore. Also, the input arg docs are gone?
|
|
||
| Depending on what type of signal we get (progress or hinted/normal), we subscribe to different endpoints. | ||
| Device mode keeps the previous progress-widget behavior: | ||
| - if no signal is provided, use the first progress signal; |
There was a problem hiding this comment.
same as above... that doc string is not useful if it references code that the PR removes
| value: float | ||
| max_value: float | ||
| done: bool | ||
| status: Literal["open", "paused", "aborted", "halt", "halted", "closed", "user_completed"] |
| "status", "open" | ||
| self.progress_tracker = BECProgressTracker(self.bec_dispatcher, parent=self) | ||
| self.progress_tracker.progress_started.connect(self._on_progress_started) | ||
| self.progress_tracker.progress_updated.connect(self._on_progress_snapshot) |
There was a problem hiding this comment.
the scan progressbar does not reset on a new scan, only on new scan progress data. If the setup takes a bit longer (e.g for moving motors to the start position), the user may get the impression that the scan doesn't run. We can solve this either by subscribing to the scan status here and simply reset it, or we broadcast 0 / 0 on a new scan from BEC. The latter could be somewhat confusing: BEC does not know at this point the max number. Probably better to simply reset the scan progressbar in BW
Description
Since this widget is present in
MainWindow, it should be rock solid. This PR replaces the custompaintEvent-based progress bar with a nativeQProgressBar.It also unifies progress handling for
ScanProgressBarandRingProgressBarthrough a shared progress backend. The scan progress widget now consumes the new progress messages emitted by BEC directly, instead of decoding scan queue state and report instructions on the widget side.One non-trivial part remains in the native progress bar styling: the dynamic stylesheet logic. This is needed to compensate for the way
QProgressBar::chunkhandles border radius, especially at low progress values, so the rounded progress fill keeps a visually correct curvature without falling back to custom painting.